'use strict';

const BaseController = require('../core/base');


function transformToOptions(tree) {
  return tree.map(item => {
    const { id: value, name: label, children } = item;
    const option = { value, label };
    if (children) {
      option.children = transformToOptions(children);
    }
    return option;
  });
}

class MenuController extends BaseController {
  // 获取菜单信息
  async menuForm() {
    const query = this.ctx.params;
    const { menu } = this.ctx.service;
    const result = await menu.findOne(query);
    if (result) {
      this.success(result);
    } else {
      this.fail();
    }
  }
  // 获取角色路由
  async permissionMenu() {
    let menuList = await this.getMenuList();
    menuList = menuList.filter(item => item.type !== 'BUTTON');
    const menuTree = await this.generateTreeMenu(menuList);
    this.success(menuTree);
  }
  // 获取路由下拉选项
  async optionsMenu() {
    const { menu } = this.ctx.service;
    const menus = await menu.find();
    const arr = await this.generateTreeMenu(menus, 'list');
    const options = transformToOptions(arr);
    this.success(options);
  }
  // 获取菜单树形
  async list() {
    const query = this.ctx.request.query;
    const { menu } = this.ctx.service;
    const menus = await menu.find(query);
    const arr = await this.generateTreeMenu(menus, 'list');
    this.success(arr);
  }
  // 构建菜单树
  async generateTreeMenu(rootList = [], type) {
    const { roles = [] } = this.ctx.state.user || {};

    const list = rootList.filter(item => item.parentId === 0);

    const addChildren = (node, dataList) => {
      const childList = dataList
        .filter(item => item.parentId === node.id)
        .map(item => addChildren(item, dataList));

      if (childList.length) {
        node.children = childList;
      }
      const { id, parentId, path, name, component, icon, redirect, children, ...rest } = node;
      let newItem = node;
      if (type !== 'list') {
        newItem = {
          path,
          component,
          redirect,
          children,
          meta: {
            title: name,
            icon,
            ...rest,
            keepAlive: true,
            hidden: false,
            roles,
          },
        };
      }
      return newItem;
    };
    return list.map(root => addChildren(root, rootList));
  }
  // 内部方法
  async getMenuList() {
    const userData = this.ctx.state.user;
    const { roleIds = [] } = userData;
    const { menu, role } = this.ctx.service;

    let roleList = await role.findAll({ id: { $in: roleIds } });
    roleList = roleList.toObject();
    // 角色菜单id
    let roleMenuIds = [];
    roleList.forEach(item => {
      const { menuIds = [] } = item;
      roleMenuIds = roleMenuIds.concat(menuIds);
    });
    // 获取所有权限后进行去重
    roleMenuIds = [ ...new Set(roleMenuIds) ];
    // 全部菜单
    let list = await menu.find();
    list = list.filter(item => roleMenuIds.includes(item.id));
    return list;
  }

  // 添加和编辑
  async save() {
    const { name } = this.ctx.request.body;
    const { id } = this.ctx.params;
    // 校验
    if (!name) return this.fail('菜单名称不能为空');
    const data = this.ctx.request.body;
    const { menu } = this.ctx.service;
    if (!id) {
      const result = await menu.save(data);
      if (!result) {
        return this.fail('新增失败');
      }
      this.success();
    } else {
      data.id = id;
      const result = await menu.save(data);
      if (!result) {
        return this.fail('更新失败');
      }
      this.success({});
    }
  }

  // 删除
  async remove() {
    const { ids = [] } = this.ctx.request.body;
    const { menu } = this.ctx.service;
    let count = 0;
    if (ids.length) {
      for (const id of ids) {
        const ret = await menu.remove(id);
        if (ret) count += 1;
      }
      this.success(count, `共删除${count}条数据`);
    } else {
      this.fail('参数错误');
    }
  }
}

module.exports = MenuController;
